package cd.zhixuan.utils.dialog;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.os.Build;
import android.provider.Settings;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import cd.zhixuan.utils.GlobalTools;

/**
 * 使用dialog实现toast效果，可控制文本变化和时间
 *
 * @author: HuZC
 * @Description: dialog toast
 * @Date: 2022/1/7
 */
public class Toaster extends IDialog {
    private static class Holder {
        static final Toaster INSTANCE = new Toaster(GlobalTools.getContext());
    }

    /**
     * 需要浮窗权限
     */
//    @RequiresPermission(Manifest.permission.SYSTEM_ALERT_WINDOW)
    public static void toast(final String text, final long during) {
        final boolean canDrawOverlays;
        if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
            //7.1.1以上需要权限
            canDrawOverlays = Settings.canDrawOverlays(GlobalTools.getContext());
        } else {
            canDrawOverlays = true;
        }
        if (!canDrawOverlays) {
            //无浮窗权限
            final Activity currentActivity = GlobalTools.getCurrentActivity();
            if (currentActivity == null) {
                //无当前activity的最终解决
                Toast.makeText(GlobalTools.getContext(), text, Toast.LENGTH_SHORT).show();
            } else {
                toast(currentActivity, text, during);
            }
            return;
        }
        Holder.INSTANCE.show(text, during);

    }

    private static Toaster activeToast;
    private static final Object syncActive = new Object();

    private static void toast(Activity activity, String text, long during) {
        if (activity == null || activity.isFinishing() || activity.isDestroyed()) return;
        synchronized (syncActive) {
            if (activity.isFinishing() || activity.isDestroyed()) return;
            Toaster toast = activeToast;
            if (toast == null || (toast.mContext != activity)) {
                if (toast != null) {
                    toast.dismiss();
                }
                toast = new Toaster(activity);
                toast.addOnIDialogListener(new OnIDialogListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        //避免一直持有activity
                        activeToast = null;
                    }

                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        //避免持有activity
                        activeToast = null;
                    }

                    @Override
                    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                        return false;
                    }

                    @Override
                    public void onShow(DialogInterface dialog) {

                    }
                });
            }
            activeToast = toast;
            toast.show(text, during);
        }
    }

    /**
     * 需要在activity结束时调用，
     * 否则在activity ondestroy时会报异常（虽然无大影响），
     * 有浮窗权限不需要
     */
    public static void destroyActiveToast() {
        final Toaster toaster = Toaster.activeToast;
        if (toaster == null) {
            return;
        }
        toaster.dismiss();

    }

    @Nullable
    private TextView toastView;

    private Toaster(@NonNull Context context) {
        super(context);
    }

    @Nullable
    @Override
    public View layoutView() {
        RelativeLayout layout = new RelativeLayout(mContext);
        layout.setLayoutParams(
                new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        FrameLayout fl = new FrameLayout(mContext);
        RelativeLayout.LayoutParams fllp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);
//        fllp.bottomMargin = (int) (0.05f * (windowRect.height()));
        fllp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
        fl.setLayoutParams(fllp);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            fl.setOutlineProvider(new ViewOutlineProvider() {

                @Override
                public void getOutline(View view, Outline outline) {
                    outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 24);
                }
            });
            fl.setClipToOutline(true);// 圆角
        }
        fl.setBackgroundColor(Color.WHITE);
        layout.addView(fl);
        //
        TextView tv = new TextView(mContext);
        tv.setTextColor(Color.LTGRAY);
        tv.setTextColor(Color.BLACK);
        tv.setTextSize(18);
        tv.setPadding(26, 14, 26, 14);
        FrameLayout.LayoutParams tvlp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                FrameLayout.LayoutParams.WRAP_CONTENT);
        tv.setLayoutParams(tvlp);
        toastView = tv;
        fl.addView(tv);

        return layout;
    }

    @Override
    public int layoutRes() {
//        return R.layout.layout_toast;
        return 0;
    }

    @Override
    public void initView() {
        setCanceledOnTouchOutside(false);
        if (rootView instanceof ViewGroup) {
            int childCount = ((ViewGroup) rootView).getChildCount();
            for (int i = 0; i < childCount; i++) {
                View childAt = ((ViewGroup) rootView).getChildAt(i);
                if (childAt instanceof TextView) {
                    toastView = (TextView) childAt;
                    break;
                }
            }
        }
        if (toastView != null) {
            //TODO
        }
    }

    /**
     * 保持一定的显示时间
     */
    public void show(String text, long during) {
        setText(text);
        super.show();
        dismiss(during);
    }

    /**
     * 延时隐藏弹框
     */
    public void dismiss(long during) {
        mHandler.removeCallbacks(dismissRunnable);
        if (during <= 0) {
            dismissRunnable.run();
            return;
        }
        mHandler.postDelayed(dismissRunnable, during);
    }

    private final Runnable dismissRunnable = new Runnable() {
        @Override
        public void run() {
            if (mContext instanceof Activity) {
                if (((Activity) mContext).isDestroyed()) {
                    return;
                }
            }
            dismiss();
        }
    };

    @Override
    protected void initWindowParams(@NonNull Window window, @NonNull WindowManager.LayoutParams lp, @NonNull WindowManager wm) {
        super.initWindowParams(window, lp, wm);
        window.clearFlags(
                WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
        window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

//        window.setWindowAnimations(android.R.style.Animation_Toast);

        lp.format = PixelFormat.TRANSLUCENT;
        lp.setTitle(getClass().getSimpleName());
        lp.windowAnimations = android.R.style.Animation_Toast;
        lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
        lp.y = (int) (0.05f * windowRect.height());
    }

    @Override
    protected void beforeShow(@NonNull Window window, @NonNull WindowManager.LayoutParams lp, @NonNull WindowManager wm) {
        super.beforeShow(window, lp, wm);

    }

    @Override
    protected void afterShowed(@NonNull Window window, @NonNull WindowManager.LayoutParams lp, @NonNull WindowManager wm) {
        super.afterShowed(window, lp, wm);
        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;

    }

    @Nullable
    public TextView getToastView() {
        return toastView;
    }

    public void setText(String text) {
        if (toastView != null)
            toastView.setText(text);
    }
}
